home *** CD-ROM | disk | FTP | other *** search
- // File: DataToRes.c
- //
- // This is a trivial application which reads a PEF container from the data fork of a file
- // and moves that information into a resource in the resource fork of the same file.
- //
- // Simce this is intended as a tool to help build code resources for SimpleApp, it
- // accepts files of type 'DPEF', converts them to 'RPEF', and creates 'RPEF' (128)
- // resources.
- //
- // This same task may be accomplished using MPW Rez.
- //
-
- #ifndef powerc
- #error This code only runs on a PowerPC machine.
- #endif
-
- #include <Types.h>
- #include <Memory.h>
- #include <Resources.h>
- #include <Quickdraw.h>
- #include <Menus.h>
- #include <Events.h>
- #include <Windows.h>
- #include <Dialogs.h>
- #include <AppleEvents.h>
- #include <StandardFile.h>
- #include <Files.h>
- #include <Errors.h>
-
- #include <FragLoad.h>
-
- // === Useful constants
- enum {
- kAppleMenu = 128,
- kFileMenu = 129,
- kOpenCommand = 1,
- kQuitCommand = 3
- };
-
- enum {
- rAboutAlert = 128,
- rErrorAlert = 129
- };
-
- enum {
- kPEFData = 'DPEF',
- kPEFResource = 'RPEF'
- };
-
- // === Global variables
- #if defined(powerc) && !defined(__MWERKS__) // Beginning with DR2, MetroWerks defines "qd" in their runtime
- QDGlobals qd;
- #endif
- Boolean gDone = false;
- Boolean gLaunchedByUser = false; // True if the user double-clicked on the app
-
- // === Function prototypes
- void Initialize (void);
- void MainLoop (void);
- void DoMouseDown (EventRecord theEvent);
- void DoMenu (long menuCode);
- void FindAndOpenPEF (void);
- OSErr ProcessFile (FSSpec fileSpec);
- pascal OSErr HandleOAPP (AEDescList *aevt, AEDescList *reply, long refCon);
- pascal OSErr HandleODOC (AEDescList *aevt, AEDescList *reply, long refCon);
- pascal OSErr HandleQUIT (AEDescList *aevt, AEDescList *reply, long refCon);
-
- // === Start of our code
- main()
- {
- Initialize();
- MainLoop();
- }
-
-
- // Initialize the ROM managers, set up our menu bar and (only) window, and
- // install our Apple event handlers.
- void Initialize()
- {
- MenuHandle appleMenu;
- MenuHandle fileMenu;
-
- // Standard "boilerplate" initialization
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(NULL);
- FlushEvents(everyEvent, 0);
-
- // Set up the menu bar
- appleMenu = GetMenu(kAppleMenu);
- if (appleMenu == NULL) {
- // Our resource file is missing! Bail out!
- ExitToShell();
- }
- AddResMenu(appleMenu, 'DRVR'); // Add Desk Accessories
- InsertMenu(appleMenu, 0);
- fileMenu = GetMenu(kFileMenu);
- InsertMenu(fileMenu, 0);
- DrawMenuBar();
-
- // Install our Apple event handlers
- AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(HandleOAPP), 0, false);
- AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerProc(HandleODOC), 0, false);
- AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(HandleQUIT), 0, false);
-
- InitCursor();
- }
-
-
- // Collect events until the user selects "Quit" (or we get a "Quit" Apple
- // event.) If we've loaded some PowerPC code, then give that code a chance
- // to execute the event first.
- void MainLoop()
- {
- EventRecord theEvent;
-
- while (!gDone) {
- WaitNextEvent(everyEvent, &theEvent, 15L, NULL);
- switch (theEvent.what) {
- case mouseDown:
- DoMouseDown(theEvent);
- break;
-
- case keyDown: {
- // See if the comamnd key is down. If it is, handle this as
- // a menu command
- char theKey = (theEvent.message & charCodeMask);
-
- if (theEvent.modifiers & cmdKey)
- DoMenu(MenuKey(theKey));
- }
- break;
-
- case updateEvt: {
- WindowPtr theWindow = (WindowPtr)theEvent.message;
-
- BeginUpdate(theWindow);
- EndUpdate(theWindow);
- }
- break;
-
- case kHighLevelEvent:
- AEProcessAppleEvent(&theEvent);
- }
- }
- }
-
- // Handle mouse clicks either in the menubar or in a window
- void DoMouseDown (EventRecord theEvent)
- {
- short part;
- WindowPtr theWindow;
-
- part = FindWindow(theEvent.where, &theWindow);
- switch (part) {
- case inMenuBar:
- DoMenu(MenuSelect(theEvent.where));
- break;
-
- case inSysWindow:
- SystemClick(&theEvent, theWindow);
- break;
-
- case inDrag: {
- Rect dragRect = qd.screenBits.bounds;
- dragRect.top = GetMBarHeight();
- DragWindow(theWindow, theEvent.where, &dragRect);
- }
- break;
- }
- }
-
-
- // Code to handle the File and Apple menus
- void DoMenu (long menuCode)
- {
- short menuID = menuCode >> 16;
- short itemID = menuCode & 0x0000FFFF;
-
- switch (menuID) {
- case kAppleMenu:
- if (itemID == 1)
- Alert(128, NULL); // Display the "About" box
- break;
-
- case kFileMenu:
- if (itemID == kOpenCommand) {
- FindAndOpenPEF();
- }
- else if (itemID == kQuitCommand)
- gDone = true;
- break;
- }
- }
-
-
- // Ask the user to locate a bit of code for us, then load
- // and execute the code
- void FindAndOpenPEF ()
- {
- // Open a file of type 'PEF ' or a resource file
- SFTypeList typeList = {kPEFData};
- StandardFileReply reply;
-
- StandardGetFile(NULL, 3, typeList, &reply);
- if (reply.sfGood)
- ProcessFile(reply.sfFile);
- }
-
-
- OSErr ReadDataFork (FSSpec fileSpec, Handle *result)
- {
- // Get the PEF data stored in the data fork of the file
- OSErr err;
- long PEFSize;
- short refNum;
-
- *result = NULL;
- err = FSpOpenDF(&fileSpec, fsCurPerm, &refNum);
- if (err) goto done;
- err = GetEOF(refNum, &PEFSize);
- if (err) goto done;
-
- // We have the file, and the size, so let's go get the data
- *result = NewHandle(PEFSize);
- err = MemError();
- if (err) goto done;
-
- HLock(*result);
- err = FSRead(refNum, &PEFSize, **result);
- HUnlock(*result);
-
- done:
- if (refNum != -1)
- FSClose(refNum);
- return err;
- }
-
-
- OSErr CreatePEFResource (FSSpec fileSpec, Handle resourceData)
- {
- // Create a RPEF resource from the supplied data
- OSErr err;
- short refNum;
-
- refNum = FSpOpenResFile(&fileSpec, fsCurPerm);
- err = ResError();
- // See if the resource fork even exists. If not, create one
- if (err == resFNotFound) {
- FSpCreateResFile(&fileSpec, 'SMPA', kPEFData, 0);
- err = ResError();
- if (err == noErr)
- // Try again
- err = CreatePEFResource(fileSpec, resourceData);
- goto done;
- }
- if (err) goto done;
-
- // The file is now open, so create our PEF resource
- AddResource(resourceData, kPEFResource, 128, (StringPtr)"\p");
- WriteResource(resourceData);
-
- done:
- if (refNum != -1)
- CloseResFile(refNum);
- return err;
- }
-
-
- OSErr ConvertToResFile (FSSpec fileSpec)
- {
- // Eradicate the data fork and change the file's type
- OSErr err;
- short refNum = -1;
- FInfo finderInfo;
-
- // Change the file's type
- err = FSpGetFInfo(&fileSpec, &finderInfo);
- if (err) goto done;
- finderInfo.fdType = kPEFResource;
- err = FSpSetFInfo(&fileSpec, &finderInfo);
- if (err) goto done;
-
- // Empty the data fork (where the old PEF container lived)
- err = FSpOpenDF(&fileSpec, fsCurPerm, &refNum);
- if (err) goto done;
- err = SetEOF(refNum,0);
- if (refNum != -1)
- CloseResFile(refNum);
-
- done:
- return err;
- }
-
-
- // Load a bit of PowerPC code which is external to this application
- OSErr ProcessFile (FSSpec fileSpec)
- {
- OSErr err = noErr;
- short refNum;
- Handle PEFData = NULL;
-
- // Stage 1 -- Get the PEF container from the data fork
- err = ReadDataFork(fileSpec, &PEFData);
- if (err) goto done;
-
- // Stage 2 -- Put this into a resource
- err = CreatePEFResource (fileSpec, PEFData);
- DisposeHandle(PEFData); PEFData = NULL;
- if (err) goto done;
-
- // Stage 3 -- Eradicate the data fork and change the file type
- err = ConvertToResFile(fileSpec);
-
- done:
- return err;
- }
-
-
- // Apple event handlers for "Open Application", "Open Document", and
- // "Quit"
- pascal OSErr HandleOAPP (AEDescList *aevt, AEDescList *reply, long refCon)
- {
- gLaunchedByUser = true;
- FindAndOpenPEF();
- return noErr;
- }
-
-
- pascal OSErr HandleODOC (AEDescList *aevt, AEDescList *reply, long refCon)
- // We'll get this if somebody double-clicks on one of our code files
- // We'll process any double-clicked or dragged-on files
- {
- AEDesc fileListDesc = {'NULL', NULL};
- long numFiles, index;
- OSErr err;
-
- err = AEGetKeyDesc( aevt, keyDirectObject, typeAEList, &fileListDesc );
- /* Count the list elements */
- err = AECountItems( &fileListDesc, &numFiles);
- if (err) goto done;
-
- /* now get each file from the list and process it. */
- /* Even though the event contains a list of alises, the Apple Event Manager */
- /* will convert each alias to an FSSpec if we ask it to. */
- for (index = 1; index <= numFiles; index ++) {
- DescType actualType;
- long actualSize;
- AEKeyword actualKeyword;
- FSSpec theFile;
-
- err = AEGetNthPtr( &fileListDesc, 1, typeFSS, &actualKeyword,
- &actualType, (Ptr)&theFile, sizeof(theFile), &actualSize);
- if (err == noErr)
- ProcessFile(theFile);
- }
-
- done:
- AEDisposeDesc(&fileListDesc); // no need to check for NULL, as AEDisposeDesc checks first
- // If the user launched us by dragging on some files, then quit
- if (!gLaunchedByUser)
- gDone = true;
- return err;
- }
-
-
- pascal OSErr HandleQUIT (AEDescList *aevt, AEDescList *reply, long refCon)
- {
- gDone = true;
- return noErr;
- }
-